# -*- coding: utf-8 -*

#Copyright (C) 2011 Daniele Simonetti
#
#This program is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 2 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

import sys, locale, string, socket, time, re, os
### PySide ###
import PySide
from threading import Thread
### UI ###
from grpeslist_ui import *
### CONTENT PROVIDERS ###
import providers
### RESOURCES ###
from myepes_rc import *
### DATE TIME ###
from datetime import timedelta, datetime, date
### ITEM DELEGATE ###
from itemdelegates.twitemdelegate import *

import gettext, locale
machine_locale = locale.getdefaultlocale()[0]
locale_dir = '/usr/share/locale'
if not os.path.exists(locale_dir):
    locale_dir = os.path.join(sys.path[0], 'locale')
t = gettext.translation('epes', locale_dir, [machine_locale])
_ = t.gettext


########## ThisWeek CLASS ############
class ThisWeek(QtGui.QWidget, Ui_GrpEpList):
  
  # Define signals
  needShowEpList        = QtCore.Signal(str)
  needBatchSerieInfo    = QtCore.Signal(list)
  
  # Class costants
  BATCH_SCALE = 3  
  
  def __init__(self, wlist, parent=None):
    super(ThisWeek, self).__init__(parent)
    self.setupUi(self)
    self.wlist = wlist
    
    self.model = ThisWeekModel(self.font(), self)
    self.tvEpList.setModel(self.model)
    self.tvEpList.header().setResizeMode(QtGui.QHeaderView.Stretch);
    self.tvEpList.setItemDelegate( TwItemDelegate(self) )
        
    # MEDIUM FONT
    med_font = QtGui.QFont(self.font().family(), 11)
    self.tvEpList.setFont(med_font)
    
    self.model.dataChanged.connect(self.update_view)

  def update(self):
    self.model.clear()    

    use_batch = True
    batch_set = []
    items = self.wlist.get_items()
    if len(items) < ThisWeek.BATCH_SCALE:
        use_batch = False

    batch = []    
    for item in items:        
        if use_batch:                
            batch.append(item['showid'])
            if len(batch) >= ThisWeek.BATCH_SCALE:
                batch_set.append(batch)
                batch = []
        else: self.needShowEpList.emit(item['showid'])
    # Add the last batch ( that could be smaller that the others )        
    if len(batch) > 0:
        batch_set.append(batch)
        
    if len(batch_set) > 0:
        print 'the work is splitted in %d batches' % len(batch_set)
        for batch in batch_set:
            self.needBatchSerieInfo.emit(batch)
    
  def event(self, e):
    if e.type() == providers.epsEventType:
      show = {}
      show['showid'] = e.source['showid']
      show['eps'] = e.eps
      self.model.calculate([show])
      self.tvEpList.expandToDepth(2)
      return True
    return super(ThisWeek, self).event(e)  
    
  def update_view(self, start, end):
      for i in range(start.row(), end.row()+1):
          parent = self.model.index(i, 0)
          child = parent.child(0, 0)
          while child.isValid():
              self.tvEpList.setFirstColumnSpanned(child.row(), parent, True)
              child = parent.child(child.row()+1, 0)
    
########## ThisWeekModel CLASS ############
class TreeItem:
  def __init__(self, data, parent = None):
    self.parent = parent
    self.stuff = data
    self.children = []
    
  def append_child(self, child):
    self.children.append(child)
    
  def get_child(self, row):
    return self.children[row]
    
  def child_count(self):
    return len(self.children)
    
  def column_count(self):
    return 1
    
  def data(self, column = 0, role = QtCore.Qt.DisplayRole):
    if column != 0:
        return None
    if role != QtCore.Qt.DisplayRole:
        return None
    try:
        value = unicode(self.stuff)
    except:
        value = str(self.stuff).decode('utf-8')
    return value
    
  def row(self):
    if self.parent is not None:
        return self.parent.children.index(self)
    return 0
	
  def __unicode__(self):
	return '%s [%d]' % ( unicode(self.stuff), self.child_count() )
 
  def __str__(self):
    return '%s [%d]' % ( str(self.stuff), self.child_count() )
    

class ThisWeekModel(QtCore.QAbstractItemModel):
  def __init__(self, font, parent=None):
    super(ThisWeekModel, self).__init__(parent)        
    self.wp = parent
    self.imap = {}
    self.items = []
    self.ep_added = []
    self.item_font = font

    #self.status_colors = { EP_STATUS_UNAIRED: QtGui.QBrush(QtGui.QColor(0xff, 0xe3, 0x59)),
    #                       EP_STATUS_AIRED: QtGui.QBrush(QtGui.QColor(0xe0, 0xe0, 0xe0)) }
    self.text_color = QtGui.QBrush(QtGui.QColor(0x15, 0x15, 0x15))
    self.item_size = QtCore.QSize(32,32)    
    self.date_font = QtGui.QFont().resolve(self.item_font)
    self.date_font.setCapitalization(QtGui.QFont.Capitalize)
    self.date_font.setBold(True)

    self.date_brush = QtGui.QBrush(QtGui.QColor(0xe0, 0xe0, 0xe0))
    self.item_brush = QtGui.QBrush(QtGui.QColor(0xff, 0xe3, 0x59))
    self.item_brush_alt = QtGui.QBrush(self.item_brush.color().lighter())
    
  def rowCount(self, parent = QtCore.QModelIndex()):
    if not parent.isValid():
        return len(self.items)
     
    parent_item = parent.internalPointer()
    if parent_item is None:
        return 0
    return parent_item.child_count()
  
  def columnCount(self, parent = QtCore.QModelIndex()):
    if parent.isValid():
        return 1
    else:
        return 2
  
  #def hasChildren(self, parent):
  #  if not parent.isValid():
  #      return False
  #  itm = parent.internalPointer()
  #  print 'parent has children? %s' % ( str(itm.child_count() > 0) )
  #  return itm.child_count() > 0

  def index(self, row, column, parent = QtCore.QModelIndex()):
    if not self.hasIndex(row, column, parent):
        return QtCore.QModelIndex()
        
    child_item = None
    if not parent.isValid():
        child_item = self.items[row]
    else:        
        parent_item = parent.internalPointer()        
        child_item = parent_item.get_child(row)
        #print 'the parent: %s, the child %s' % (unicode(parent_item), unicode(child_item))
        
        
    if child_item is not None:
        return self.createIndex(row, column, child_item)
    return QtCore.QModelIndex()
    
  def parent(self, index):
    if not index.isValid():
        #print 'parent: index not valid %d, %d' % (index.row(), index.column())
        return QtCore.QModelIndex()
    
    try:
        child_item = index.internalPointer()
        parent_item = child_item.parent    
    except:
        parent_item = None
    
    if parent_item is None:
        #print 'parent: parent item null %d, %d' % (index.row(), index.column())
        return QtCore.QModelIndex()
    
    #print 'parent of %s is %s' % ( unicode(child_item), unicode(parent_item) )
    return self.createIndex(parent_item.row(), 0, parent_item)    
    
  def data(self, index, role):
    if role == QtCore.Qt.DisplayRole:
        #print 'data for index %d,%d' % (index.row(), index.column())
        #if index.parent().isValid():
            #print 'parent is %d,%d' % (index.parent().row(), index.parent().column())
        return self.data_display(index)
    elif role == QtCore.Qt.UserRole:
        return None
    elif role == QtCore.Qt.SizeHintRole:
        return self.item_size
    elif role == QtCore.Qt.FontRole:
        return self.data_font(index)
    elif role == QtCore.Qt.BackgroundRole:
        return self.data_bg(index)
    elif role == QtCore.Qt.ForegroundRole:
        return self.text_color
    else:
        return None
    
  def data_display(self, index):   
    if not index.isValid():  
        return None
    
    parent = index.parent()
    item = index.internalPointer()

    if index.column() == 1:
        if not parent.isValid():
            return item.child_count()
        else:
            return ' '
    elif index.column() == 0:
        return item.data(index.column())
    return None
  
  def data_font(self, index):
    if not index.isValid():
        return None
    if not index.parent().isValid():
        return self.date_font
    return self.item_font

  def data_bg(self, index):
    if not index.isValid():
        return None
    if not index.parent().isValid():
        return self.date_brush
    if ( index.row() % 2 ) != 0:
        return self.item_brush_alt
    return self.item_brush
  
  def clear(self):
    self.imap = {}
    self.items = []
    self.ep_added = []
       
    self.start_of_week = datetime.today().date()
    td = timedelta(days=self.start_of_week.weekday())   
    self.start_of_week = self.start_of_week - td

    td = timedelta(days=6)    
    self.end_of_week = self.start_of_week + td
    
    td = timedelta(days=1)
    dt = self.start_of_week
    root = None
    for i in range(0, 7):              
        dt_s = dt.strftime("%A %d %B")
        root = TreeItem(dt_s)
        self.items.append(root)
        self.imap[dt] = root
        dt = dt + td  

  def headerData(self, section, orientation, role):
    return None

  def flags(self, index):
    if not index.isValid():
        return None
    return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
  
  def calculate(self, shows):       
    #print str(start_of_week)
    #print str(end_of_week)
    parent = None    
    for s in shows:
        for e in s['eps']:
            try:            
                dt = e.airdate[0:10]
                ep_dt = datetime.strptime(dt, '%Y-%m-%d').date()
            except:
                ep_dt = date.min
                print 'invalid date format %s' % (e.airdate[0:10])
            
            if ep_dt >= self.start_of_week and ep_dt <= self.end_of_week:
                if ep_dt not in self.imap: 
                    ep_dt_s = ep_dt.strftime("%A %d %B")
                    parent = TreeItem(ep_dt_s)
                    self.items.append(parent)
                    self.imap[ep_dt] = parent
                else:
                    parent = self.imap[ep_dt]
                    
                if e not in self.ep_added:
                    itm = TreeItem(e.showname + ' - ' + unicode(e), parent)
                    self.ep_added.append(e)
                    parent.append_child(itm)

    self.emit(QtCore.SIGNAL('dataChanged(QModelIndex, QModelIndex)'), 
    self.index(0,0), self.index(len(self.items)-1,0))   

        
